#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
统一日志模块

提供项目中统一的日志管理，支持按天切分和统一格式
"""

import logging
import logging.handlers
import os
import sys
import traceback
from datetime import datetime
from typing import Optional, Dict, Any
import json

# 尝试导入配置模块，如果失败则使用默认配置
try:
    from ..utils.config import get_log_config
    _config_available = True
except ImportError:
    _config_available = False


class UnifiedFormatter(logging.Formatter):
    """统一日志格式器"""
    
    def __init__(self, include_module_info: bool = True):
        self.include_module_info = include_module_info
        super().__init__()
    
    def format(self, record):
        # 基础格式
        timestamp = datetime.fromtimestamp(record.created).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
        level = record.levelname
        logger_name = record.name
        message = record.getMessage()
        
        # 构建日志条目
        log_parts = [
            f"[{timestamp}]",
            f"[{level:8}]",
            f"[{logger_name:20}]",
            message
        ]
        
        # 添加模块信息
        if self.include_module_info and hasattr(record, 'module') and hasattr(record, 'funcName'):
            module_info = f"{record.module}.{record.funcName}:{record.lineno}"
            log_parts.insert(-1, f"[{module_info:30}]")
        
        # 添加异常信息
        if record.exc_info:
            exc_text = self.formatException(record.exc_info)
            log_parts.append(f"\n{exc_text}")
        
        return " ".join(log_parts)


class DailyRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
    """按天轮转的文件处理器"""
    
    def __init__(self, filename, when='midnight', interval=1, backupCount=30, encoding='utf-8'):
        super().__init__(
            filename=filename,
            when=when,
            interval=interval,
            backupCount=backupCount,
            encoding=encoding
        )
        self.suffix = "%Y-%m-%d"


class UnifiedLogger:
    """统一日志管理器"""
    
    def __init__(self, log_dir: str = None, log_level: str = None):
        # 从配置文件获取日志配置，如果配置不可用则使用默认值
        if _config_available:
            try:
                log_config = get_log_config()
                self.log_dir = log_dir or os.path.dirname(log_config.get('file', 'logs/webdav.log'))
                self.log_level = getattr(logging, (log_level or log_config.get('level', 'INFO')).upper(), logging.INFO)
                self.log_file = log_config.get('file', 'logs/webdav.log')
            except Exception:
                # 如果配置获取失败，使用默认值
                self.log_dir = log_dir or "logs"
                self.log_level = getattr(logging, (log_level or "INFO").upper(), logging.INFO)
                self.log_file = os.path.join(self.log_dir, "webdav.log")
        else:
            # 配置模块不可用，使用默认值
            self.log_dir = log_dir or "logs"
            self.log_level = getattr(logging, (log_level or "INFO").upper(), logging.INFO)
            self.log_file = os.path.join(self.log_dir, "webdav.log")
        
        self.loggers = {}
        self._ensure_log_dir()
        self._setup_root_logger()
    
    def _ensure_log_dir(self):
        """确保日志目录存在"""
        if not os.path.exists(self.log_dir):
            os.makedirs(self.log_dir)
    
    def _setup_root_logger(self):
        """设置根日志器"""
        # 使用配置的日志文件路径
        log_file = self.log_file
        
        # 文件处理器 - 按天轮转
        file_handler = DailyRotatingFileHandler(
            filename=log_file,
            when='midnight',
            interval=1,
            backupCount=30,  # 保留30天的日志
            encoding='utf-8'
        )
        file_handler.setFormatter(UnifiedFormatter(include_module_info=True))
        
        # 控制台处理器
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setFormatter(UnifiedFormatter(include_module_info=False))
        
        # 配置根日志器
        root_logger = logging.getLogger()
        root_logger.setLevel(self.log_level)
        root_logger.handlers.clear()
        root_logger.addHandler(file_handler)
        root_logger.addHandler(console_handler)
        
        # 防止重复日志
        root_logger.propagate = False
    
    def get_logger(self, name: str) -> logging.Logger:
        """获取日志器"""
        if name not in self.loggers:
            logger = logging.getLogger(name)
            logger.setLevel(self.log_level)
            # 不添加处理器，使用根日志器的处理器
            logger.propagate = True
            self.loggers[name] = logger
        return self.loggers[name]
    
    def log_with_context(self, logger_name: str, level: str, message: str, 
                        context: Dict[str, Any] = None, exc_info: bool = False):
        """记录带上下文的日志"""
        logger = self.get_logger(logger_name)
        log_method = getattr(logger, level.lower())
        
        if context:
            context_str = " | ".join([f"{k}={v}" for k, v in context.items()])
            full_message = f"{message} | {context_str}"
        else:
            full_message = message
        
        log_method(full_message, exc_info=exc_info)
    
    def log_performance(self, logger_name: str, operation: str, duration: float, 
                       success: bool = True, extra_info: Dict[str, Any] = None):
        """记录性能日志"""
        status = "SUCCESS" if success else "FAILED"
        context = {
            "operation": operation,
            "duration_ms": f"{duration:.2f}",
            "status": status
        }
        if extra_info:
            context.update(extra_info)
        
        self.log_with_context(logger_name, "INFO", f"性能监控", context)
    
    def log_error(self, logger_name: str, error: Exception, context: str = "", 
                 extra_info: Dict[str, Any] = None):
        """记录错误日志"""
        error_context = {
            "error_type": type(error).__name__,
            "error_message": str(error),
            "context": context
        }
        if extra_info:
            error_context.update(extra_info)
        
        self.log_with_context(logger_name, "ERROR", f"错误发生", error_context, exc_info=True)
    
    def log_security_event(self, logger_name: str, event_type: str, 
                          user: str = "", ip: str = "", details: Dict[str, Any] = None):
        """记录安全事件日志"""
        security_context = {
            "event_type": event_type,
            "user": user,
            "ip": ip
        }
        if details:
            security_context.update(details)
        
        self.log_with_context(logger_name, "WARNING", f"安全事件", security_context)
    
    def log_business_event(self, logger_name: str, event: str, 
                          user: str = "", details: Dict[str, Any] = None):
        """记录业务事件日志"""
        business_context = {
            "event": event,
            "user": user
        }
        if details:
            business_context.update(details)
        
        self.log_with_context(logger_name, "INFO", f"业务事件", business_context)
    
    def get_log_config_info(self) -> Dict[str, Any]:
        """获取当前日志配置信息"""
        return {
            "log_dir": self.log_dir,
            "log_file": self.log_file,
            "log_level": logging.getLevelName(self.log_level),
            "config_available": _config_available,
            "logger_count": len(self.loggers)
        }


# 全局日志管理器实例
_unified_logger = None


def init_unified_logging(log_dir: str = None, log_level: str = None):
    """初始化统一日志系统"""
    global _unified_logger
    _unified_logger = UnifiedLogger(log_dir, log_level)
    return _unified_logger


def get_logger(name: str) -> logging.Logger:
    """获取日志器"""
    if _unified_logger is None:
        init_unified_logging()
    return _unified_logger.get_logger(name)


def log_performance(logger_name: str, operation: str, duration: float, 
                   success: bool = True, extra_info: Dict[str, Any] = None):
    """记录性能日志"""
    if _unified_logger is None:
        init_unified_logging()
    _unified_logger.log_performance(logger_name, operation, duration, success, extra_info)


def log_error(logger_name: str, error: Exception, context: str = "", 
             extra_info: Dict[str, Any] = None):
    """记录错误日志"""
    if _unified_logger is None:
        init_unified_logging()
    _unified_logger.log_error(logger_name, error, context, extra_info)


def log_security_event(logger_name: str, event_type: str, 
                      user: str = "", ip: str = "", details: Dict[str, Any] = None):
    """记录安全事件日志"""
    if _unified_logger is None:
        init_unified_logging()
    _unified_logger.log_security_event(logger_name, event_type, user, ip, details)


def log_business_event(logger_name: str, event: str, 
                      user: str = "", details: Dict[str, Any] = None):
    """记录业务事件日志"""
    if _unified_logger is None:
        init_unified_logging()
    _unified_logger.log_business_event(logger_name, event, user, details)


# 装饰器
def log_execution_time(logger_name: str = "performance"):
    """记录函数执行时间的装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            start_time = datetime.now()
            try:
                result = func(*args, **kwargs)
                end_time = datetime.now()
                duration = (end_time - start_time).total_seconds() * 1000  # 毫秒
                log_performance(logger_name, func.__name__, duration, True)
                return result
            except Exception as e:
                end_time = datetime.now()
                duration = (end_time - start_time).total_seconds() * 1000  # 毫秒
                log_performance(logger_name, func.__name__, duration, False)
                log_error(logger_name, e, f"函数 {func.__name__} 执行失败")
                raise
        return wrapper
    return decorator


def log_errors(logger_name: str = "error"):
    """记录函数错误的装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                log_error(logger_name, e, f"函数 {func.__name__} 发生错误")
                raise
        return wrapper
    return decorator


if __name__ == "__main__":
    # 测试统一日志系统
    print("=== 统一日志系统测试 ===")
    
    # 初始化日志系统
    unified_logger = init_unified_logging()
    
    # 显示配置信息
    config_info = unified_logger.get_log_config_info()
    print(f"日志配置信息:")
    for key, value in config_info.items():
        print(f"  {key}: {value}")
    print()
    
    # 测试基础日志
    logger = get_logger("test")
    logger.debug("调试信息")
    logger.info("普通信息")
    logger.warning("警告信息")
    logger.error("错误信息")
    
    # 测试性能日志
    log_performance("test", "test_operation", 123.45, True, {"file_size": "1MB"})
    
    # 测试错误日志
    try:
        raise ValueError("测试错误")
    except Exception as e:
        log_error("test", e, "测试上下文", {"user": "testuser"})
    
    # 测试安全事件日志
    log_security_event("test", "login_failed", "testuser", "127.0.0.1", {"attempts": 3})
    
    # 测试业务事件日志
    log_business_event("test", "file_upload", "testuser", {"file": "test.txt", "size": "1MB"})
    
    print("统一日志系统测试完成")
